﻿using hutil;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace Base.WCS.Common {
    public enum ExceptionCode : byte {
        NO_ERROR = 0,
        IllegalFunction = 1,
        IllegalDataAddress = 2,
        IllegalDataValue = 3,
        SlaveDeviceFalure = 4,
        Acknowledge = 5,
        SlaveDeviceBusy = 6,
        MemoryPartiyError = 8,
        GatewayPathUnavailable = 10,
        GatewayTargetDeviceFailedToRespond = 11
    }
    public class ModbusUtil {
        public static void CheckErr(byte[] result,short transaction_id,byte _identifier) {
            if(result == null || result.Length == 0) {
                throw new IOException("Received no data slave exception response");
            }
                if(result.Length < 9) {
                    throw new IOException("Received WRONG_MESSAGE_LEN slave exception response" + result.Length);
                }
                if(result[7] > 128 && result[8] != 0) {
                    bool flag5 = Enum.IsDefined(typeof(ExceptionCode),result[8]);
                    if(flag5) {
                        throw new IOException("Received ExceptionCode slave exception response" + ((ExceptionCode)result[8]).ToString());
                    }
                }
                short id = (short)ModbusByteUtil.GetUShort(result.Take(2).ToArray<byte>());
                if(transaction_id != id) {
                    throw new IOException(" WRONG_TRANSACTION_ID  exception response" + id);
                }
                bool flag7 = ModbusByteUtil.GetUShort(new byte[]
                {
                        result[2],
                        result[3]
                }) > 0;
                if(flag7) {
                    throw new IOException(" WRONG_PROTOCOL_ID  exception response" + id);
                }
                ushort uShort = ModbusByteUtil.GetUShort(new byte[]
                {
                        result[4],
                        result[5]
                });
                bool flag8 = result.Length - 7 + 1 < (int)uShort;
                if(flag8) {
                    throw new IOException(" WRONG_MESSAGE_LEN  exception response");
                }
                if(_identifier != result[6]) {
                    throw new IOException(" WRONG_RESPONSE_UNIT_ID  exception response");
                }
            }
        public static byte[] readHoldingRegistersHeader(byte identifier,ushort start_address,ushort len) {
            ushort message_len = 6;
            if(len < 1) {
                throw new Exception("modbus read len less");
            };
            if(len < 1) {
                throw new Exception("modbus read len too long");
            };
            List<byte> list = new List<byte>(7);
            list.InsertRange(0,ModbusByteUtil.GetBytes((short)0));//this.transaction_id
            list.InsertRange(2,ModbusByteUtil.GetBytes((short)0));
            list.InsertRange(4,ModbusByteUtil.GetBytes((short)message_len));
            list.Insert(6,identifier);
            list.Add(3);
            list.AddRange(ModbusByteUtil.GetBytes((short)start_address));
            list.AddRange(ModbusByteUtil.GetBytes((short)len));
            byte[] result = list.ToArray();
            return result;
        }
        public static byte[] BuildMBAPHeader(byte identifier,ushort message_len) {
            List<byte> list = new List<byte>(7);
            list.InsertRange(0,ModbusByteUtil.GetBytes((short)0));//this.transaction_id
            list.InsertRange(2,ModbusByteUtil.GetBytes((short)0));
            list.InsertRange(4,ModbusByteUtil.GetBytes((short)message_len));
            list.Insert(6,identifier);
            return list.ToArray();
        }
        public static byte[] BulidReadCoilsTelex(ushort start_address,ushort len) {
            bool flag2 = len > 2000;
            if(flag2) {
                return null;
            } 
            List<byte> list = new List<byte>();
            list.Add(1);
            list.AddRange(ModbusByteUtil.GetBytes((short)start_address));
            list.AddRange(ModbusByteUtil.GetBytes((short)len));
            return list.ToArray();
        }
        public static byte[] BulidReadHoldingRegistersTelex(ushort start_address,ushort len) {
            List<byte> list = new List<byte>();
            list.Add(3);
            list.AddRange(ModbusByteUtil.GetBytes((short)start_address));
            list.AddRange(ModbusByteUtil.GetBytes((short)len));
            byte[] result = list.ToArray();
            return result;
        }
    }
}
